from typing import List

import numpy
import pandas as pd

import specific_state_changes, output_graphics, output_table
import contract_network
import daily_diagnosis_neighbor
# 记录当天各种状态下个体数量的列表
list_N = []
list_R = []
list_NN = []
list_N_A = []
list_R_A = []
list_NN_A =[]

non_existent = []
state_0 = []
state_1 = []
state_2 = []
state_3 = []
recover = []
isolation_0 = []
isolation_1: List[int] = []
isolation_2 = []
diagnose = []
death = []

# 记录每天各种状态下个体数量的列表
S = []
H = []
IN = []
A = []
IS = []
C = []
D = []
R = []
infected = []
Total = []

# 特殊个体以及特殊指的记录
diagnosis_rate_is = []    # 隔离确诊率
diagnosis_rate = []       # 未隔离确诊率
one_lurker_state_everyday = []
one_susceptible_state_everyday = []
one_isolation_state_everyday = []
list_person = []
list_isolation = []
state_0_1 = []
state_1_3 = []
state_i_1 = []
state_i_2 = []
state_i_3 = []
state_person_is2 = []
c_state_1 = []
c_state_2 = []
c_state_3 = []

# p_id_person state lable1_person state lable2
p_id_1 = []  # 当天该状态所有个体的id值
p_id_2 = []
p_id_3 = []
p_id_4 = []
p_id_5 = []
p_id_10 = []
p_id_10_1 = []
p_id_10_0 =[]
p_id_1_2 = []
p_id_1_3 = []
p_id_1_4 = []
p_id_1_5 = []
p_id_2_3 = []
p_id_2_4 = []
p_id_2_5 = []
p_id_3_4 = []
p_id_3_5 = []
is_1 = []
is_2_new = []
is_2_old = []
is_id_0_1 = []
is_id_0_2 = []
is_id_1_2 = []
is_id_1_0 = []
is_id_2_3 = []
is_id_2_0 = []
# p_id_3_5 = []
# is_id_0_5 = []
# is_id_1_5 = []
# 记录时间与记录个体序号配对
p_t_1 = [] # 每一天该状态个体的数量
p_t_2 = []
p_t_3 = []
p_t_4 = []
p_t_5 = []
p_t_10 = []
p_t_10_1 = []
p_t_10_0 = []
p_t_1_2 = []
p_t_1_3 = []
p_t_1_4 = []
p_t_1_5 = []
p_t_2_3 = []
p_t_2_4 = []
p_t_2_5 = []
p_t_3_4 = []
p_t_3_5 = []
is_t_0_1 = []
is_t_0_2 = []
is_t_1_2 = []
is_t_1_0 = []
is_t_2_3 = []
is_t_2_0 = []
# p_t_3_5 = []
# is_t_0_5 = []
# is_t_1_5 = []
is_t_2_new = []


change_num_is2 = []
rate_confrimed = []
rate_t_confrimed = []

parameter_file_main = pd.read_table('input_file\parameter_file_main.txt', header=None)
N = parameter_file_main[1][0]    # 总人数
Day = parameter_file_main[1][1]  # 天数
Frequency = parameter_file_main[1][2]   # 输入每天更新个体状态的频率

Frequency_total = Day * Frequency  # 根据每天状态更新频数设置总体更新次数
# 初始化主程序和接触网络
test = specific_state_changes.city(N, Day, Frequency)
# matrix = simu_ncov.small_world_NW(N, 4, 0.01854)  # 初始化接触网络
# print(matrix)
network = contract_network.society_network(1, 4, N, 10, 2, 5, 1)

matrix = network.Network_initialization()

empty_list = numpy.random.randint(0, N, size=0)  # 初始城市空位
print("产生空位为：", empty_list)

test.begin(empty_list, Frequency)  # 对于一些参数的初始定义以及城市个体状态的初始赋值

# test.adjustment_parameter(hz)

for t in range(0, Frequency_total):  # 循环每次个体更新
    print("这是第", t, "天")

    # 更新接触网络，以及某些参数
    test.update(t, matrix)  # 更新天数，调整参数
    # print(test.person)
    network.avg_quantities()
    matrix = network.update_everyday(test.isolation_people)

    del list_N[:]
    del list_R[:]
    del list_NN[:]
    # 删除每天记录的参数，用于新一天的记录
    del state_0[:]
    del state_1[:]
    del state_2[:]
    del state_3[:]
    del isolation_0[:]
    del isolation_1[:]
    del diagnose[:]
    del death[:]
    del recover[:]
    # 删除状态变化个体记录数组
    del p_id_1[:]
    del p_id_2[:]
    del p_id_3[:]
    del p_id_4[:]
    del p_id_5[:]
    del p_id_10[:]
    del p_id_10_1[:]
    del p_id_10_0[:]
    del p_id_1_2[:]
    del p_id_1_3[:]
    del p_id_1_4[:]
    del p_id_1_5[:]
    del p_id_2_3[:]
    del p_id_2_4[:]
    del p_id_2_5[:]
    del p_id_3_4[:]
    del p_id_3_5[:]
    del is_1[:]
    del is_2_new[:]
    del is_2_old[:]
    del is_id_0_1[:]
    del is_id_0_2[:]
    del is_id_1_2[:]
    del is_id_1_0[:]
    del is_id_2_3[:]
    del is_id_2_0[:]
    rate_confrimed = 0
    for p_id in range(0, N):  # 对每个个体的状态更新
        # 记录不存在个体数
        if test.cloning_isolation_state[p_id] == -1:  # 判断是否是不在城市空位
            non_existent.append(p_id)  # 记录当天不在城市空位
        # 对未隔离个体的处理
        elif test.cloning_isolation_state[p_id] == 0:  # 判断是否是未隔离个体
            isolation_0.append(p_id)  # 记录当天未隔离个体
            # 未隔离-易感-接触过携带病毒者
            if test.cloning_person[p_id] == 0:  # 判断是否是未隔离且未标记（没有接触过病毒的）个体
                state_0.append(p_id)  # 记录当天未隔离-易感个体

            elif test.cloning_person[p_id] == 10:  # 判断是否是未隔离-标记（有感染风险，接触过携带病毒者）的个体
                infected.append(test.un_isolation_person_0(matrix, p_id, p_id_10, p_id_10_1,list_R,list_N))   # 状态转移，按照未隔离-标记进行按照风险系数的发生概率
                test.un_isolation_judge.append(p_id)  # 记录未隔离-标记类型个体
                state_0.append(p_id)  # 记录当天未隔离-易感个体

            # 未隔离-潜伏
            elif test.cloning_person[p_id] == 1:  # 判断是否是未隔离-潜伏个体
                # P1 = testp.un_isolation_infect_risk()
                test.transfer(p_id)  # 将参数设置为未隔离下的参数（这些概率用于状态转移概率计算）
                test.un_isolation_person_1(p_id, p_id_1, p_id_1_2, p_id_1_3, p_id_1_4)  # 状态转移
                state_1.append(p_id)  # 记录当天未隔离潜伏者个体
                # print("潜伏个体：", p_id)
                state_0_1.append(p_id)  # 记录程序中产生的所有未隔离潜伏个体

            # 未隔离-感染
            elif test.cloning_person[p_id] == 2:  # 判断是否是未隔离-感染个体
                test.un_isolation_person_2(p_id, p_id_2, p_id_2_3, p_id_2_4)
                state_2.append(p_id)
                # print("感染个体：", p_id)
                state_i_2.append(p_id)
                rate_confrimed=test.b

            elif test.cloning_person[p_id] == 3:
                state_3.append(p_id)
                test.un_isolation_person_3(p_id, p_id_3, p_id_3_5, is_id_0_2)
                # b = testp.unislation_infect_risk
                # print("无症状个体：", p_id)

            elif test.cloning_person[p_id] == 4:
                recover.append(p_id)

        # 对隔离个体的处理
        elif test.cloning_isolation_state[p_id] == 1:
            test.transfer(p_id)
            test.isolation_person(p_id, is_1,is_id_1_0, is_id_1_2)
            isolation_1.append(p_id)
            test.isolation_person_state.append(p_id)
            # print("隔离个体：", p_id)

        # 对确诊个体的处理
        elif test.cloning_isolation_state[p_id] == 2:
            # print("确诊个体：", p_id)
            diagnose.append(p_id)
            # 利用新增确诊寻找密切接触者
            if test.cloning_treatment_time[p_id] == 1:
                test.new_diagnosis(matrix, p_id, is_2_new, is_t_0_1, is_id_0_2, list_NN)

            else:
                # 所有旧确诊的个体直接进行治疗
                test.recovery_and_death(p_id, is_2_old, is_id_2_3, is_id_2_0)

        elif test.cloning_isolation_state[p_id] == 3:
            death.append(p_id)
            # print("死亡个体：", p_id)
    try:
        avg_N = sum(list_N)/len(list_N)
    except:
        avg_N = 0

    try:
        avg_R = (sum(list_R)/len(list_R))
    except:
        avg_R = 0


    try:
        avg_NN = (sum(list_NN)/len(list_NN))
    except:
        avg_NN = 0

    list_N_A.append(avg_N)
    list_R_A.append(avg_R)
    list_NN_A.append(avg_NN)
    # 计算确诊率
    diagnosis_rate_is.append(test.isolation_diagnosis_rate())
    diagnosis_rate.append(test.un_isolation_diagnosis_rate())
    # 删除(记录状态转变个体)数列中重复元素
    p_id_1 = list(set(p_id_1))
    p_id_2 = list(set(p_id_2))
    p_id_3 = list(set(p_id_3))
    p_id_4 = list(set(p_id_4))
    p_id_5 = list(set(p_id_5))
    p_id_10 = list(set(p_id_10))
    p_id_10_1 = list(set(p_id_10_1))
    p_id_10_0 = list(set(p_id_10_0))
    p_id_1_2 = list(set(p_id_1_2))
    p_id_1_3 = list(set(p_id_1_3))
    p_id_1_4 = list(set(p_id_1_4))
    p_id_1_5 = list(set(p_id_1_5))
    p_id_2_3 = list(set(p_id_2_3))
    p_id_2_4 = list(set(p_id_2_4))
    p_id_2_5 = list(set(p_id_2_5))
    p_id_3_4 = list(set(p_id_3_4))
    p_id_3_5 = list(set(p_id_3_5))
    is_1 = list(set(is_1))
    is_2_new = list(set(is_2_new))
    is_2_old = list(set(is_2_old))
    is_id_0_1 = list(set(is_id_0_1))
    is_id_0_2 = list(set(is_id_0_2))
    is_id_1_2 = list(set(is_id_1_2))
    is_id_1_0 = list(set(is_id_1_0))
    is_id_2_3 = list(set(is_id_2_3))
    is_id_2_0 = list(set(is_id_2_0))
    # 记录每天的个体装换状态个数
    p_t_1.append(len(p_id_1))
    p_t_2.append(len(p_id_2))
    p_t_3.append(len(p_id_3))
    p_t_4.append(len(p_id_4))
    p_t_5.append(len(p_id_5))
    p_t_10.append(len(p_id_10))
    p_t_10_1.append(len(p_id_10_1))
    p_t_10_0.append(len(p_id_10_0))
    p_t_1_2.append(len(p_id_1_2))
    p_t_1_3.append(len(p_id_1_3))
    p_t_1_4.append(len(p_id_1_4))
    p_t_1_5.append(len(p_id_1_5))
    p_t_2_3.append(len(p_id_2_3))
    p_t_2_4.append(len(p_id_2_4))
    p_t_2_5.append(len(p_id_2_5))
    p_t_3_4.append(len(p_id_3_4))
    p_t_3_5.append(len(p_id_3_5))
    is_t_0_1.append(len(is_id_0_1))
    is_t_0_2.append(len(is_id_0_2))
    is_t_1_2.append(len(is_id_1_2))
    is_t_1_0.append(len(is_id_1_0))
    is_t_2_3.append(len(is_id_2_3))
    is_t_2_0.append(len(is_id_2_0))
    is_t_2_new.append(len(is_2_new))
    change_num_is2.append(len(is_2_old))
    rate_t_confrimed.append(rate_confrimed)
    # c_state_1.append(len(c1))
    # c_state_2.append(len(c2))
    # c_state_3.append(len(c3))


    # 记录投放的一个潜伏者的个体状态变化
    one_lurker_state_everyday.append(test.person[test.throw_num[0]])
    # 记录一个最开始是易感者的个体状态变化
    one_susceptible_state_everyday.append(test.isolation_state[test.throw_num[0]])
    # 记录一个隔离者的隔离状态变化
    # one_isolation_state_everyday.append(test.isolation_state[test.isolation_person_state[0]])

    # 更新记录每天不同个体状态的人数列表
    S.append(len(state_0))
    H.append(len(state_1))
    IN.append(len(state_3))
    A.append(len(state_2))
    R.append(len(recover))
    IS.append(len(isolation_1))
    C.append(len(diagnose))
    D.append(len(death))
    Total.append(len(state_0) + len(state_1) + len(state_2) + len(state_3) + len(recover) + len(isolation_1) + len(
        diagnose) + len(death))
    # print("潜伏个体为：", state_1)
    # print("感染个体为：", state_2)
    # print("无症状个体为：", state_3)
    # print("隔离个体为：", isolation_1)
    # print("确诊易感个体为：", diagnose)
    # print("死亡个体为：", death)

    # 将当天所有人的状态存入总的状态列表
    list_person.append(list(test.person))
    list_isolation.append((list(test.isolation_state)))

    # 获取当天的新增确诊者的邻居编号以及邻居的状态
    # daily_diagnosis_neighbor.output_neighbor()
    print("第" + str(t) + "天所有确诊者的邻居状态以及其隔离状态", end=" ")
    daily_diagnosis_neighbor.print_neighbor_state(test.person)
    daily_diagnosis_neighbor.print_neighbor_isolation_state(test.isolation_state)

# 将状态列表转换为以更新次数为行序号，以个体ID为列序号的二维矩阵，并状态属性定义为整形
arr_person = numpy.array(list_person)
arr_isolation = numpy.array(list_isolation)
arr_person = arr_person.astype(numpy.int)
arr_isolation = arr_isolation.astype(numpy.int)

output_graphics = output_graphics.output_graphics(arr_person, arr_isolation, Frequency_total, N)
output_table = output_table.output_table(arr_person, arr_isolation, Frequency_total, N)

test.throw_num.extend(numpy.random.randint(0, N, size=7))
# output_graphics.special_individual_change(test.throw_num)

output_graphics.plt_sum(S, H, A, IN, R, IS, C, D, Total)

#
date_in = 20
try:
    element = [(p_t_1_2[date_in]/p_t_1[date_in]),(p_t_1_3[date_in]/p_t_1[date_in]),(p_t_1_4[date_in]/p_t_1[date_in])]
    lable = ['1 to 2','1 to 3','1 to 4']
    output_graphics.relation(element, lable, img_title='潜伏者状态转变各个类型占比')
except:
    print('潜伏者的值为零')
#
try:
    element = [(p_t_10_1[date_in]/p_t_10[date_in]), (1-p_t_10_1[date_in]/p_t_10[date_in])]
    lable = ['10 to 1', '其他（10 to 10,10 to 0）']
    output_graphics.relation(element, lable, img_title='被标记的状态转变各个类型占比')
except:
    print('被标记的状态数量为零')
#
try:
    print(p_t_2_3[date_in] + ' ' + p_t_2[date_in])
    element = [(p_t_2_3[date_in]/p_t_2[date_in]),(p_t_2_4[date_in]/p_t_2[date_in]),(p_t_2_5[date_in]/p_t_2[date_in])]
    lable = ['2 to 3','2 to 4','2 to 5']
    output_graphics.relation(element, lable, img_title='无症状状态转变各个类型占比')
except:
    print('当天无症状的值为零')
#
try:
    element = [(p_t_3_4[date_in]/p_t_3[date_in]), (p_t_3_5[date_in]/p_t_3[date_in])]
    lable = ['3 to 4', '3 to 5']
    output_graphics.relation(element, lable, img_title='有症状状态转变各个类型占比')
except:
    print('当天有症状的值为零')


# 状态转移过程end
# 每天新增确诊统计
print("个体感染风险：", infected)
print("每一天的确诊率：", diagnosis_rate)
# print(test.throw_num[0], "号个体（初始投放的潜伏者）的个体状态", one_lurker_state_everyday)
# print(test.un_isolation_judge[0], "号个体（需要检测的易感者）的个体状态", one_susceptible_state_everyday)
print("恢复的人数", R)
print("总人数：", Total)
print("标记平均接触人数：", list_N_A)
print("标记平均感染风险：", list_R_A)
print("确诊平均接触人数", list_NN_A)
print("pt_10", p_t_10)

output_table.output_table_summary(diagnosis_rate_is, diagnosis_rate, S, H, IN, A, R, IS, C, D, Total)
output_table.data_10(p_t_10, p_t_10_1, list_R_A)
output_table.data_confrimed(is_t_2_new, change_num_is2, is_t_2_0, is_t_2_3,  is_t_2_new, network.touch_d,list_NN_A, IS)
output_table.data_3(IN, p_t_3, is_t_0_2, p_t_3_5, test.rate_3_to_5, rate_t_confrimed)
output_table.data_2(A, test.rate_2_to_3, test.rate_2_to_4, p_t_2, p_t_2_3, p_t_2_4)
output_table.data_1(H, test.rate_1_to_2, test.rate_1_to_3, test.rate_1_to_4, p_t_1, p_t_1_2, p_t_1_3, p_t_1_4)
print(network.touch_d)

